package com.mdd.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.yulichang.query.MPJQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mdd.admin.LikeAdminThreadLocal;
import com.mdd.admin.validate.commons.PageValidate;
import com.mdd.admin.service.IDeptFlowService;
import com.mdd.admin.validate.DeptFlowCreateValidate;
import com.mdd.admin.validate.DeptFlowUpdateValidate;
import com.mdd.admin.validate.DeptFlowSearchValidate;
import com.mdd.admin.vo.DeptFlowListedVo;
import com.mdd.admin.vo.DeptFlowDetailVo;
import com.mdd.admin.vo.system.SystemAuthDeptVo;
import com.mdd.common.config.GlobalConfig;
import com.mdd.common.core.PageResult;
import com.mdd.common.entity.DeptFlow;
import com.mdd.common.entity.FlowNode;
import com.mdd.common.entity.Node;
import com.mdd.common.entity.NodeRole;
import com.mdd.common.entity.system.SystemAuthAdmin;
import com.mdd.common.entity.system.SystemAuthDept;
import com.mdd.common.entity.system.SystemAuthPost;
import com.mdd.common.entity.system.SystemAuthRole;
import com.mdd.common.mapper.DeptFlowMapper;
import com.mdd.common.mapper.FlowNodeMapper;
import com.mdd.common.mapper.NodeMapper;
import com.mdd.common.mapper.NodeRoleMapper;
import com.mdd.common.mapper.system.SystemAuthAdminMapper;
import com.mdd.common.mapper.system.SystemAuthDeptMapper;
import com.mdd.common.mapper.system.SystemAuthPostMapper;
import com.mdd.common.mapper.system.SystemAuthRoleMapper;
import com.mdd.common.util.ListUtils;
import com.mdd.common.util.TimeUtils;
import com.mdd.common.util.UrlUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.*;

/**
 * 部门流程关联实现类
 * @author LikeAdmin
 */
@Service
public class DeptFlowServiceImpl implements IDeptFlowService {
        
    @Resource
    DeptFlowMapper deptFlowMapper;
    @Resource
    SystemAuthDeptMapper systemAuthDeptMapper;
    @Resource
    SystemAuthAdminMapper systemAuthAdminMapper;
    @Resource
    SystemAuthPostMapper systemAuthPostMapper;
    @Resource
    SystemAuthRoleMapper systemAuthRoleMapper;
    @Resource
    FlowNodeMapper flowNodeMapper;
    @Resource
    NodeMapper nodeMapper;
    @Resource
    NodeRoleMapper nodeRoleMapper;

    /**
     * 部门流程关联列表
     *
     * @author LikeAdmin
     * @param pageValidate 分页参数
     * @param searchValidate 搜索参数
     * @return PageResult<DeptFlowListedVo>
     */
    @Override
    public PageResult<DeptFlowListedVo> list(PageValidate pageValidate, DeptFlowSearchValidate searchValidate) {
        Integer page  = pageValidate.getPageNo();
        Integer limit = pageValidate.getPageSize();

        QueryWrapper<DeptFlow> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_delete", 0);
        queryWrapper.orderByDesc("id");

        deptFlowMapper.setSearch(queryWrapper, searchValidate, new String[]{
            "=:depId@dep_id:int",
            "=:type:str",
            "=:proposalType@proposal_type:str",
            "=:configProposal@config_proposal:str",
            "=:isBasics@is_basics:str",
            "=:userId@user_id:int",
            "like:userName@user_name:str",
            "=:updateUserId@update_user_id:int",
            "like:updateUserName@update_user_name:str",
        });

        IPage<DeptFlow> iPage = deptFlowMapper.selectPage(new Page<>(page, limit), queryWrapper);

        List<DeptFlowListedVo> list = new LinkedList<>();
        for(DeptFlow item : iPage.getRecords()) {
            DeptFlowListedVo vo = new DeptFlowListedVo();
            BeanUtils.copyProperties(item, vo);
            vo.setCreateTime(TimeUtils.timestampToDate(item.getCreateTime()));
            vo.setUpdateTime(TimeUtils.timestampToDate(item.getUpdateTime()));
            list.add(vo);
        }

        return PageResult.iPageHandle(iPage.getTotal(), iPage.getCurrent(), iPage.getSize(), list);
    }

    @Override
    public PageResult<SystemAuthDeptVo> deptList(PageValidate pageValidate, DeptFlowSearchValidate searchValidate) {
        Integer page  = pageValidate.getPageNo();
        Integer limit = pageValidate.getPageSize();

        QueryWrapper<SystemAuthDept> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_delete", 0);
        queryWrapper.eq("id",searchValidate.getDepId()).or().eq("pid",searchValidate.getDepId());
        queryWrapper.orderByAsc("id");

        systemAuthDeptMapper.setSearch(queryWrapper, searchValidate, new String[]{
                "=:name:str",
        });

        IPage<SystemAuthDept> iPage = systemAuthDeptMapper.selectPage(new Page<>(page, limit), queryWrapper);

        List<SystemAuthDeptVo> list = new LinkedList<>();
        for(SystemAuthDept item : iPage.getRecords()) {
            SystemAuthDeptVo vo = new SystemAuthDeptVo();
            DeptFlow deptFlows = deptFlowMapper.selectOne(new QueryWrapper<DeptFlow>().eq("type", searchValidate.getType())
                    .eq("dep_id", item.getId())
                    .eq("is_delete", 0));
            vo.setDeptFlow(deptFlows);
            BeanUtils.copyProperties(item, vo);
            list.add(vo);
        }

        return PageResult.iPageHandle(iPage.getTotal(), iPage.getCurrent(), iPage.getSize(), list);
    }

    /**
     * 部门流程关联详情
     *
     * @author LikeAdmin
     * @param id 主键参数
     * @return DeptFlow
     */
    @Override
    public DeptFlowDetailVo detail(Integer id) {
        DeptFlow model = deptFlowMapper.selectOne(
                new QueryWrapper<DeptFlow>()
                    .eq("id", id)
                    .eq("is_delete", 0)
                    .last("limit 1"));

        Assert.notNull(model, "数据不存在");

        DeptFlowDetailVo vo = new DeptFlowDetailVo();
        BeanUtils.copyProperties(model, vo);
        return vo;
    }

    @Override
    public DeptFlowDetailVo detailByAll(Integer deptid, String type) {
        DeptFlow model = deptFlowMapper.selectOne(
                new QueryWrapper<DeptFlow>()
                        .eq("dep_id", deptid)
                        .eq("type",type)
                        .eq("is_delete", 0)
                        .last("limit 1"));

        Assert.notNull(model, "数据不存在");

        DeptFlowDetailVo vo = new DeptFlowDetailVo();
        BeanUtils.copyProperties(model, vo);
        FlowNode flowNode = flowNodeMapper.selectOne(new QueryWrapper<FlowNode>().eq("dept_flow_id", model.getId())
                .eq("is_delete", 0));
        vo.setFlowNode(flowNode);
        List<Node> nodes = nodeMapper.selectList(new QueryWrapper<Node>().eq("flow_node_id", flowNode.getId())
                .eq("is_delete", 0));
        for (Node node : nodes) {
            List<NodeRole> nodeRoles = nodeRoleMapper.selectList(new QueryWrapper<NodeRole>().eq("node_id", node.getId())
                    .eq("is_delete", 0));
            for (NodeRole nodeRole : nodeRoles) {
                if (node.getPersonnelType().equals("用户")) {
                    nodeRole.setAuthAdmin(systemAuthAdminMapper.selectOne(new QueryWrapper<SystemAuthAdmin>().eq("id", nodeRole.getAdminUserId())
                            .eq("is_delete", 0)));
                }
                if (node.getPersonnelType().equals("角色")) {
                    nodeRole.setAuthRole(systemAuthRoleMapper.selectOne(new QueryWrapper<SystemAuthRole>().eq("id", nodeRole.getRoleId())
                            .eq("is_delete", 0)));
                }
                if (node.getPersonnelType().equals("岗位")) {
                    nodeRole.setAuthPost(systemAuthPostMapper.selectOne(new QueryWrapper<SystemAuthPost>().eq("id", nodeRole.getPostId())
                            .eq("is_delete", 0)));
                }
            }
        }
        vo.setNodes(nodes);
        return vo;
    }

    @Override
    public DeptFlowDetailVo detailByDeptId(String proposalType,String type) {
        Integer adminId = LikeAdminThreadLocal.getAdminId();
        SystemAuthAdmin admin = systemAuthAdminMapper.selectOne(new QueryWrapper<SystemAuthAdmin>().eq("id", adminId));
        DeptFlow model = deptFlowMapper.selectOne(
                new QueryWrapper<DeptFlow>()
                        .eq("dep_id", admin.getDeptIds())
                        .eq("type", type)
                        .like("proposal_type",proposalType)
                        .eq("is_delete", 0)
                        .last("limit 1"));

        Assert.notNull(model, "数据不存在");

        DeptFlowDetailVo vo = new DeptFlowDetailVo();
        BeanUtils.copyProperties(model, vo);
        FlowNode flowNode = flowNodeMapper.selectOne(new QueryWrapper<FlowNode>().eq("dept_flow_id", model.getId())
                .eq("is_delete", 0));
        vo.setFlowNode(flowNode);
        List<Node> nodes = nodeMapper.selectList(new QueryWrapper<Node>().eq("flow_node_id", flowNode.getId())
                .eq("is_delete", 0));
        for (Node node : nodes) {
            List<NodeRole> nodeRoles = nodeRoleMapper.selectList(new QueryWrapper<NodeRole>().eq("node_id", node.getId())
                    .eq("is_delete", 0));
            for (NodeRole nodeRole : nodeRoles) {
                if (node.getPersonnelType().equals("用户")) {
                    nodeRole.setAuthAdmin(systemAuthAdminMapper.selectOne(new QueryWrapper<SystemAuthAdmin>().eq("id", nodeRole.getAdminUserId())
                            .eq("is_delete", 0)));
                }
                if (node.getPersonnelType().equals("角色")) {
                    nodeRole.setAuthRole(systemAuthRoleMapper.selectOne(new QueryWrapper<SystemAuthRole>().eq("id", nodeRole.getRoleId())
                            .eq("is_delete", 0)));
                }
                if (node.getPersonnelType().equals("岗位")) {
                    nodeRole.setAuthPost(systemAuthPostMapper.selectOne(new QueryWrapper<SystemAuthPost>().eq("id", nodeRole.getPostId())
                            .eq("is_delete", 0)));
                }
            }
        }
        vo.setNodes(nodes);
        return vo;
    }

    /**
     * 部门流程关联新增
     *
     * @author LikeAdmin
     * @param createValidate 参数
     */
    @Override
    public void add(DeptFlowCreateValidate createValidate) {
            DeptFlow model = new DeptFlow();
            model.setDepId(createValidate.getDeptId());
            model.setType(createValidate.getType());
            model.setProposalType(createValidate.getProposalType());
            model.setConfigProposal(createValidate.getConfigProposal());
            model.setIsBasics(createValidate.getIsBasics());
            model.setUserId(LikeAdminThreadLocal.getAdminId());
            model.setUserName(LikeAdminThreadLocal.get("username").toString());
            model.setCreateTime(String.valueOf(System.currentTimeMillis() / 1000));
            model.setUpdateUserId(LikeAdminThreadLocal.getAdminId());
            model.setUpdateUserName(LikeAdminThreadLocal.get("username").toString());
            model.setUpdateTime(String.valueOf(System.currentTimeMillis() / 1000));
            model.setIsDelete(0);
            deptFlowMapper.insert(model);
            createValidate.getFlowNode().setDeptFlowId(model.getId());
            createValidate.getFlowNode().setUserId(LikeAdminThreadLocal.getAdminId());
            createValidate.getFlowNode().setUserName(LikeAdminThreadLocal.get("username").toString());
            createValidate.getFlowNode().setCreateTime(String.valueOf(System.currentTimeMillis() / 1000));
            createValidate.getFlowNode().setUpdateUserId(LikeAdminThreadLocal.getAdminId());
            createValidate.getFlowNode().setUpdateUserName(LikeAdminThreadLocal.get("username").toString());
            createValidate.getFlowNode().setUpdateTime(String.valueOf(System.currentTimeMillis() / 1000));
            createValidate.getFlowNode().setIsDelete(0);
            flowNodeMapper.insert(createValidate.getFlowNode());
            common(createValidate.getNodes(),createValidate.getFlowNode().getId());
    }

    /**
     * 部门流程关联编辑
     *
     * @author LikeAdmin
     * @param updateValidate 参数
     */
    @Override
    public void edit(DeptFlowUpdateValidate updateValidate) {
        DeptFlow model = deptFlowMapper.selectOne(
                new QueryWrapper<DeptFlow>()
                    .eq("id",  updateValidate.getId())
                    .eq("type",updateValidate.getType())
                    .eq("is_delete", 0)
                    .last("limit 1"));

        Assert.notNull(model, "数据不存在!");

        model.setId(updateValidate.getId());
        model.setDepId(updateValidate.getDepId());
        model.setType(updateValidate.getType());
        model.setProposalType(updateValidate.getProposalType());
        model.setConfigProposal(updateValidate.getConfigProposal());
        model.setIsBasics(updateValidate.getIsBasics());
        model.setUpdateUserId(LikeAdminThreadLocal.getAdminId());
        model.setUpdateUserName(LikeAdminThreadLocal.get("username").toString());
        model.setUpdateTime(String.valueOf(System.currentTimeMillis() / 1000));
        deptFlowMapper.updateById(model);
        FlowNode deptFlow = flowNodeMapper.selectOne(new QueryWrapper<FlowNode>().eq("dept_flow_id", model.getId())
                .eq("is_delete", 0));
        updateValidate.getFlowNode().setId(deptFlow.getId());
        updateValidate.getFlowNode().setDeptFlowId(model.getId());
        updateValidate.getFlowNode().setUpdateUserId(LikeAdminThreadLocal.getAdminId());
        updateValidate.getFlowNode().setUpdateUserName(LikeAdminThreadLocal.get("username").toString());
        updateValidate.getFlowNode().setUpdateTime(String.valueOf(System.currentTimeMillis() / 1000));
        flowNodeMapper.updateById(updateValidate.getFlowNode());
        List<Node> nodes = nodeMapper.selectList(new QueryWrapper<Node>().eq("flow_node_id", updateValidate.getFlowNode().getId())
                .eq("is_delete", 0));
        for (Node item: nodes){
            List<NodeRole> nodeRoles = nodeRoleMapper.selectList(new QueryWrapper<NodeRole>().eq("node_id", item.getId())
                    .eq("is_delete", 0));
            for (NodeRole itemRole: nodeRoles){
                itemRole.setIsDelete(1);
                itemRole.setDeleteTime(String.valueOf(System.currentTimeMillis() / 1000));
                nodeRoleMapper.updateById(itemRole);
            }
            item.setIsDelete(1);
            item.setDeleteTime(String.valueOf(System.currentTimeMillis() / 1000));
            nodeMapper.updateById(item);
        }
        common(updateValidate.getNodes(),updateValidate.getFlowNode().getId());
    }

    //新增修改公用方法
    public void common(List<Node> nodes,Integer flowNodeId){
        for (Node item: nodes) {
            item.setFlowNodeId(flowNodeId);
            item.setUserId(LikeAdminThreadLocal.getAdminId());
            item.setUserName(LikeAdminThreadLocal.get("username").toString());
            item.setCreateTime(String.valueOf(System.currentTimeMillis() / 1000));
            item.setUpdateUserId(LikeAdminThreadLocal.getAdminId());
            item.setUpdateUserName(LikeAdminThreadLocal.get("username").toString());
            item.setUpdateTime(String.valueOf(System.currentTimeMillis() / 1000));
            item.setIsDelete(0);
            nodeMapper.insert(item);
            for (Integer id : item.getRoleIds()) {
                NodeRole nodeRole = new NodeRole();
                nodeRole.setNodeId(item.getId());
                if (item.getPersonnelType().equals("用户")) {
                    nodeRole.setUserId(id);
                }
                if (item.getPersonnelType().equals("角色")) {
                    nodeRole.setRoleId(id);
                }
                if (item.getPersonnelType().equals("岗位")) {
                    nodeRole.setPostId(id);
                }
                nodeRole.setUserId(LikeAdminThreadLocal.getAdminId());
                nodeRole.setUserName(LikeAdminThreadLocal.get("username").toString());
                nodeRole.setCreateTime(String.valueOf(System.currentTimeMillis() / 1000));
                nodeRole.setUpdateUserId(LikeAdminThreadLocal.getAdminId());
                nodeRole.setUpdateUserName(LikeAdminThreadLocal.get("username").toString());
                nodeRole.setUpdateTime(String.valueOf(System.currentTimeMillis() / 1000));
                nodeRole.setIsDelete(0);
                nodeRoleMapper.insert(nodeRole);
            }
        }
    }


    /**
     * 部门流程关联删除
     *
     * @author LikeAdmin
     * @param id 主键ID
     */
    @Override
    public void del(Integer id) {
        DeptFlow model = deptFlowMapper.selectOne(
                new QueryWrapper<DeptFlow>()
                    .eq("id", id)
                    .eq("is_delete", 0)
                    .last("limit 1"));

        Assert.notNull(model, "数据不存在!");

        model.setIsDelete(1);
        model.setDeleteTime(String.valueOf(System.currentTimeMillis() / 1000));
        deptFlowMapper.updateById(model);
    }

}
